using Sirenix.OdinInspector;
using System.Linq;
using UnityEngine;
using UnityEngine.Audio;

namespace LFramework 
{
    public class GameEntry : MonoBehaviour
    {
        [FoldoutGroup("UI框架相关")]
        [Header("默认分辨率宽")]
        public float DefaultWidth;

        [FoldoutGroup("UI框架相关")]
        [Header("默认分辨率高")]
        public float DefaultHeight;

        [FoldoutGroup("UI框架相关")]
        [Header("UI摄像机")]
        public Camera UICamera;

        [FoldoutGroup("UI框架相关")]
        [Header("UI分组")]
        public UIGroup[] UIGroups;

        [FoldoutGroup("声音相关")]
        [Header("声音容器")]
        public GameObject AudioContanier;
        [FoldoutGroup("声音相关")]
        [Header("声音混合器")]
        public AudioMixer MonsterMixer;
        [FoldoutGroup("声音相关")]

        #region 管理器

        public static UIManager UI;
        public static PoolManager Pool;
        public static TimeManager Timer;
        public static LSceneManager Scene;
        public static ProcedureManager Procedure;
        public static HttpManager Http;
        public static FsmManager Fsm;
        public static EventManager Event;
        public static DataTableManager DataTable;
        public static AudioManager Audio;
        public static AssetsManager AssetsLoader;
        public static SocketManager Socket;
        public static PlayerPrefsManager PlayerPrefs;
        public static WebSocketManager WebSocket;

        #endregion

        public static GameEntry Instance { get; private set; }
        private void Awake()
        {
            Log("GameEntry.OnAwake()");
            Instance = this;
            DontDestroyOnLoad(this);
        }

        private void Start()
        {
            Log("GameEntry.OnStart()");

            PlayerPrefs = new PlayerPrefsManager();
            UI = new UIManager();
            Pool = new PoolManager();
            Timer = new TimeManager();
            Scene = new LSceneManager();
            Procedure = new ProcedureManager();
            Http = new HttpManager();
            Fsm = new FsmManager();
            Event = new EventManager();
            DataTable = new DataTableManager();
            AssetsLoader = new AssetsManager();
            Audio = new AudioManager();
            Socket = new SocketManager();
            WebSocket = new WebSocketManager();

            //初始化 管理器,管理器依赖的数据需要在构造函数中写，防止管理器之间的互相引用
            UI.Init(UIGroups, DefaultWidth, DefaultHeight);
            Procedure.Init();
            DataTable.Init();
            Socket.Init();
            Audio.Init();

            //最后 启动游戏 流程
            Procedure.CurrFsm.ChangeState((int)ProcedureManager.EState.Launch);
        }

        void Update()
        {
            Timer.OnUpdate(Time.deltaTime);
            Pool.OnUpdate();
            Procedure.OnUpdate();
            AssetsLoader.OnUpdata();
            Scene.OnUpdate();
            Socket.OnUpdate();
            WebSocket.OnUpdate();
            Audio.OnUpdate();
        }

        private void OnDestroy()
        {
            Socket.Dispose();
            WebSocket.Dispoase();
            UI.Dispose();
            Pool.Dispose();
            Timer.Dispose();
            Scene.Dispose();
            Procedure.Dispose();
            Http.Dispose();
            Fsm.Dispose();
            Event.Dispose();
            DataTable.Dispose();
            Audio.Dispose();
            //最后释放
            AssetsLoader.Dispose();
        }

        private void OnApplicationQuit()
        {
            PlayerPrefs.SaveDataAll();
        }
        private void OnApplicationPause(bool pause)
        {
            if (pause)
            {
                PlayerPrefs.SaveDataAll();
            }
        }

        public static void Log(params object[] args)
        {
#if DEBUG_LOG_NORMAL
            Debug.Log("GameEntryLog - " + args.Aggregate("", (current, message) => current + (" - " + message)));
#endif
        }

        public static void LogWarning(params object[] args)
        {
#if DEBUG_LOG_WARNING
            Debug.LogWarning("GameEntryLog - " + args.Aggregate("", (current, message) => current + (" - " + message)));
#endif
        }

        public static void LogError(params object[] args)
        {
#if DEBUG_LOG_ERROR
            Debug.LogError("GameEntryLog - " + args.Aggregate("", (current, message) => current + (" - " + message)));
#endif
        }
    }
}
